home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
bbsutil
/
dlx70bbs.zip
/
DLX70SRC.ZIP
/
KBD.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-01-19
|
16KB
|
573 lines
TITLE KBD Interace to MS Pascal
;
; Keyboard: Special Concurrent I/O Package for DLX
; Non-busy wait I/O
; Programmed by Richard Gillmann
;
; DLX Bulletin Board System V7.0
;
; FREEWARE NOTICE
;
; DLX V7.0 is placed in the public domain by its author, Richard Gillmann.
; Anyone who wishes to may run the program, copy it, or modify it for
; any purpose, including commercial gain.
;
; This package assumes that the display is in 80 column alpha mode
; It also assumes DOS 2 or higher
;
wrapcol equ 79 ; hard wrap at this column
in_len equ 120 ; number of characters in incoming buffer
f_len equ 10 ; number of characters in function key buffer
ctrl_c equ 3 ; ascii control c
bell equ 7 ; ascii bell character
bs equ 8 ; ascii backspace character
tab equ 9 ; ascii tab character
lf equ 10 ; ascii linefeed character
cr equ 13 ; ascii carriage return character
ctrl_o equ 15 ; ascii control o
ctrl_q equ 17 ; ascii control q
ctrl_s equ 19 ; ascii control s
del equ 255 ; ascii del character
nattr equ 7 ; normal video attribute
dos equ 21h ; dos function call
true equ 1 ; ms pascal true
false equ 0 ; ms pascal false
page
pushem macro
push bp
mov bp,sp
push ds
endm
popem macro
pop ds
pop bp
endm
page
extrn screen_ptr:word
extrn row0:byte,col0:byte,lmc0:byte,wrap0:byte,bs_local:byte;
extrn stifled:byte,cancelled:byte,skipped:byte
data segment para public 'data'
columns db 80 ; columns/row
ecco dw 1 ; echo flag: -1=echoing +1=not echoing
cr_count db 0 ; carriage return count
soft_cr db 0 ; was last carriage return a soft one?
; incoming buffer
inbuf db in_len dup(?) ; incoming buffer
in_cnt dw 0 ; count of characters in the buffer
in_head dw inbuf ; head buffer offset
in_tail dw inbuf ; tail buffer offset
; function key buffer
fbuf db f_len dup(?) ; function key buffer
f_cnt dw 0 ; count of characters in fkey buffer
f_head dw fbuf ; fkey head buffer offset
f_tail dw fbuf ; fkey tail buffer offset
tabsiz db 8 ; tab spacing
data ends
dgroup group data
page
code segment para public 'code'
assume cs:code
public f_count ; return count of function keys typed
public f_recv ; read function key
public kr_count ; return count of chars in incoming buffer
public k_recv ; read next char from incoming buffer
public echo_kbd ; re-enable echoing
public installh ; install our interrupt handler
public restoreh ; restore DOS interrupt handler
public purgekbd ; empty kbd buffer
public kbd_soft ; was last cr a soft one?
key_io label word ; word equivalent of
key_io2 dd ? ; address of normal key interrupt handler
page
;
; internal routine
; direct screen write
; write char in al to current row,col
;
assume ds:dgroup
dsw proc near
push es ; save extra segment
push ax ; save char
mov ax,screen_ptr+2 ; segment of screen buffer
mov es,ax ; to extra segment
assume es:nothing
mov al,row0 ; row
mul columns ; * 80
add al,col0 ; + column
adc ah,0 ; (carry)
sal ax,1 ; double to allow for attribute bytes
mov bx,ax ; copy result to index register
pop ax ; restore character
mov es:[bx],al ; direct write
pop es ; restore extra segment
assume es:dgroup
ret ; done
dsw endp
page
;
; internal routine
; advance cursor
; scrolling is the responsibility of higher levels
;
assume ds:dgroup
advance proc near
inc col0 ; next column
cmp col0,80 ; past last column?
jb adv_x ; jump if not
mov col0,0 ; to column
inc row0 ; next row
adv_x: ret ; done
advance endp
page
;
; internal routine: display a character
; char in al, preserved by this call
;
assume ds:dgroup
display proc near
push ax ; save char
; branch if special char
cmp bs_local,1 ; handle this ourselves?
jne dis_0 ; jump if not
cmp al,bs ; backspace?
je dis_1 ; jump if so
cmp al,del ; del?
je dis_1 ; jump if so
dis_0: cmp al,cr ; carriage return?
je dis_2 ; jump if so
cmp al,bell ; bell?
je dis_4 ; jump if so
cmp al,' ' ; printable character?
jb dis_x ; jump if not
; normal char
call dsw ; direct screen write
call advance ; advance the cursor
jmp short dis_x ; finish
; backspace or del
dis_1: mov dl,lmc0 ; left margin column
cmp col0,dl ; already at left margin?
jbe dis_x ; jump if so
dec col0 ; back one column
mov al,' ' ; ascii space character
call dsw ; direct screen write
jmp short dis_x ; finish
; carriage return
dis_2: mov col0,0 ; column zero
jmp short dis_x ; finish
; bell
dis_4: push si ; save si
mov ah,14 ; write tty
int 10h ; bios video tty beep
pop si ; restore si
; exit
dis_x: mov ah,2 ; set cursor posn
mov dh,row0 ; row
mov dl,col0 ; column
mov bh,0 ; first page
int 10h ; bios video function
pop ax ; restore char
ret ; done
display endp
page
;
; internal routine
; add character to input buffer
;
assume ds:dgroup
stuff proc near
cmp in_cnt,in_len ; is the buffer full?
jae st_2 ; exit if so
mov bx,in_head ; head ptr
mov 0[bx],al ; store char in buffer
inc bx ; bump ptr
mov cx,offset dgroup:inbuf ; input buffer
add cx,in_len ; ptr to end of buffer
cmp bx,cx ; past the end?
jb st_1 ; jump if not
mov bx,offset dgroup:inbuf ; wrap if so
st_1: mov in_head,bx ; update pointer
inc in_cnt ; bump count
st_2: cmp al,cr ; carriage return?
jne st_x ; jump if not
inc cr_count ; bump carriage return count
st_x: ret ; done
stuff endp
;
; internal routine
; remove most recent character from input buffer
;
assume ds:dgroup
unstuff proc near
cmp in_cnt,0 ; is the buffer empty?
je un_x ; exit if so
mov bx,in_head ; head ptr
mov cx,offset dgroup:inbuf ; input buffer
cmp bx,cx ; at the beginning?
ja un_1 ; jump if not
mov bx,offset dgroup:inbuf ; if so,
add bx,in_len ; then wrap
un_1: dec bx ; dink ptr
mov in_head,bx ; update pointer
dec in_cnt ; dink count
cmp byte ptr 0[bx],cr ; was it a carriage return?
jne un_x ; jump if not
dec cr_count ; dink carriage return count
un_x: ret ; done
unstuff endp
page
;
; buffer and display incoming character
; char in al
;
assume ds:dgroup
b_and_d proc near
; backspace and del
cmp bs_local,1 ; process bs ourselves
jne bd_2 ; jump if not
cmp al,bs ; backspace character?
je bd_1 ; jump if so
cmp al,del ; del character?
jne bd_2 ; jump if not
bd_1: call unstuff ; remove latest character
jmp short bd_3 ; continue
; pseudo word wrap
bd_2: cmp al,' ' ; blank?
je bd_2a ; jump if so
cmp al,tab ; tab?
jne bd_2b ; jump if not
bd_2a: mov bl,wrap0 ; wrap on space column
cmp col0,bl ; wrap on space?
jb bd_2b ; jump if not
mov al,cr ; substitute a carriage return
mov soft_cr,true ; a soft one
; normal character
bd_2b: call stuff ; insert character in buffer
; display character and advance cursor
bd_3: cmp ecco,-1 ; are we echoing?
jne bd_x ; jump if not
call display ; display character
; check for line wrap
mov bl,col0 ; no. of characters so far
cmp bl,wrapcol ; line too long?
jb bd_4 ; jump if not
cmp bl,wrap0 ; line way too long?
jae bd_3a ; do fake cr if so
cmp wrap0,wrapcol ; about to overflow display line?
ja bd_5 ; avoid this
bd_3a: mov al,cr ; else fake a carriage return
mov soft_cr,true ; a soft one
jmp bd_2 ; put it in inbuf & display it
; treat carriage return specially
bd_4: cmp al,cr ; carriage return?
jne bd_x ; jump if not
bd_5: mov ecco,1 ; stop echoing
bd_x: ret ; done
b_and_d endp
page
;
; internal routine
; add character to function key buffer
;
assume ds:dgroup
bufunc proc near
cmp f_cnt,f_len ; is the buffer full?
jae bf_x ; exit if so
mov bx,f_head ; head ptr
mov 0[bx],ah ; store key number in buffer
inc bx ; bump ptr
mov cx,offset dgroup:fbuf ; function key buffer
add cx,f_len ; ptr to end of buffer
cmp bx,cx ; past the end?
jb bf_1 ; jump if not
mov bx,offset dgroup:fbuf ; wrap if so
bf_1: mov f_head,bx ; update pointer
inc f_cnt ; bump count
bf_x: ret ; done
bufunc endp
page
;
; internal routine
; key interrupt handler
;
assume ds